package io.hd;

import io.Archivo;
import io.red.GestorRed;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Mariano Zapata
 */
public class GestorArchivo {
    
    private GestorRed gr;
    private List<ControladorArchivo> controladores;
    
    private static final int TAMANIO_BUFFER= 1024;
    private static final String DIRECTORIO= "temp/";
    
    public GestorArchivo(GestorRed gr)
    {
        this.gr= gr;
        controladores= new ArrayList<ControladorArchivo>();
        this.controlarDirectorio();
    }
    
    public void crearArchivoEnServidor(File archivo, BufferedOutputStream salidaRed)
            throws FileNotFoundException, IOException
    {
        byte [] buf= new byte[TAMANIO_BUFFER];
        FileInputStream streamArchivo= new FileInputStream(archivo);
        int n= -1;
        while ((n= streamArchivo.read(buf)) > -1)
            salidaRed.write(buf, 0, n);
        streamArchivo.close();
        archivo.delete();
    }
    
    public void abrirArchivo(Archivo archivo, BufferedInputStream entradaRed) throws IOException
    {
        File f= new File(DIRECTORIO + archivo.obtenerId() + "_" + archivo.getNombre()); //PARA QUE EL NOMBRE SEA ÚNICO.
        f.createNewFile();
        byte [] buf= new byte[TAMANIO_BUFFER];
        FileOutputStream streamArchivo= new FileOutputStream(f);
        int n= -1;
        while ((n= entradaRed.read(buf)) > -1)
            streamArchivo.write(buf, 0, n);
        streamArchivo.close();
        ControladorArchivo ca= new ControladorArchivo(archivo, f, this);
        controladores.add(ca);
        ca.start();
    }
    
    public void cerrarArchivo(Archivo archivo, boolean guardar, BufferedOutputStream salidaRed)
            throws FileNotFoundException, IOException
    {
        File f= new File(DIRECTORIO + archivo.obtenerId() + "_" + archivo.getNombre());
        if (guardar)
        {
            byte [] buf= new byte[TAMANIO_BUFFER];
            FileInputStream streamArchivo= new FileInputStream(f);
            int n= -1;
            while ((n= streamArchivo.read(buf)) > -1)
                salidaRed.write(buf, 0, n);
            streamArchivo.close();
        }
        f.delete();
    }
    
    public void cerrarArchivoEliminado(Archivo archivo)
    {
        for (ControladorArchivo c : controladores)
        {
            if (c.obtenerArchivoLogico().equals(archivo))
            {
                File f= new File(DIRECTORIO + archivo.obtenerId() + "_" + archivo.getNombre());
                c.destruir();
                controladores.remove(c);
                f.delete();
                return;
            }
        }
    }
    
    public boolean hayArchivosAbiertos() {return (controladores.size() > 0);}
    
    public List<Archivo> obtenerArchivosAbiertos()
    {
        List<Archivo> abiertos= new ArrayList<Archivo>();
        for (ControladorArchivo ca : controladores)
            abiertos.add(ca.obtenerArchivoLogico());
        return abiertos;
    }
    
    public void aplicacionExternaCerrada(ControladorArchivo ca)
    {
        controladores.remove(ca);
        gr.aplicacionExternaCerrada(ca.obtenerArchivoLogico());
    }
    
    public void errorAbrirAplicacion(Archivo archivo, String mensaje, ControladorArchivo ca)
    {
        controladores.remove(ca);
        gr.errorAbrirAplicacion(archivo, mensaje);
    }
    
    public void destruirAplicacionesExternas()
    {
        for (ControladorArchivo ca : controladores)
        {
            ca.destruir();
            controladores.remove(ca);
        }
    }
    
    private void controlarDirectorio()
    {
        File dir= new File(DIRECTORIO);
        File [] archs= dir.listFiles();
        for (File f : archs)
            f.delete();
    }
}
